package fflib.container
{
	use namespace iterator;
	
	/**
	 * Iterator für einfach verkette Listen.
	 * 
	 * Letzte Änderung: 10.08.2008
	 */
	public class SListIterator implements IIterator
	{
		/**
		 * @private
		 */
		private var p_data: SLinkedList;
		
		/**
		 * @private
		 */
		private var p_position: int;
		
		/**
		 * @private
		 */
		iterator var p_node: SLinkedListNode;
		
		public function SListIterator(list: SLinkedList) {
			p_data     = list;
			p_position = 0;
			p_node     = p_data.p_first;
		}
		
		/**
		 * Setzt den Iterator auf Anfangsbedingungen zurück.
		 * 
		 * @return Den zurückgesetzten Iterator.
		 * 
		 * @see #end()
		 */
		public function begin(): IIterator {
			p_position = 0;
			p_node     = p_data.p_first;
			
			return this;
		}
		
		/**
		 * Gibt das Ende des Iterators zurück.
		 * 
		 * @return Die letzte mögliche Position.
		 * 
		 * @see #begin()
		 */
		public function end(): int {
			return p_data.size() - 1;
		}
		
		public function get position(): int {
			return p_position;
		}
		
		public function set position(value : int): void {
			var i: int = p_position;
			var d: int = value - i;
			
			if (i == value || value < 0 || value > p_data.size() - 1)
				return;
			
			if (i < value)
				for (i = 0; i < d; i++)
					p_node = p_node.next;
			else {
				p_node = p_data.p_first;
				for (i = 0; i < value; i++)
					p_node = p_node.next;
			}
			
			p_position = i;
		}
		
		/**
		 * Gibt das aktuelle Item zurück, auf das der Iterator zeigt.
		 * 
		 * @return Das aktuelle Item.
		 * 
		 * @see #next()
		 */
		public function current(): * {
			var node: * = p_node.data;
			
			if (p_node.next == null) {
				p_position = p_data.size() - 1;
				return node;
			}
			return node;
		}
		
		/**
		 * Gibt das aktuelle Item zurück, auf das der Iterator zeigt.<br />
		 * Im gegensatz zu Iterator::current zeigt der Iterator danach auf das
		 * nächste Item.
		 * 
		 * @return Das aktuelle Item.
		 * 
		 * @see #current()
		 */
		public function next(): * {
			var node: * = this.current();
			this.position++;
			return node;
		}
		
		/**
		 * Gibt <code>true</code> zurück, falls Iterator::end noch nicht erreicht ist.
		 * 
		 * @return Ein boolescher Wert, ob das Ende der Liste erreicht worden ist.
		 * 
		 * @see #end()
		 * @see #next()
		 */
		public function hasNext(): Boolean {
			return p_position != p_data.size() - 1;
		}
	}
}



